import javax.swing.*;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 参考:http://www.importnew.com/16436.html
 */
public class LambdaExample {

    //匿名类
    public static void newThread(String message) {
        new Thread(() -> System.out.println(message)).start();
    }

    public static void buttonListener() {
        JButton show = new JButton("Show");
        show.addActionListener((e) -> System.out.println("lambda expression for buttonListener"));
    }

    public static void forList() {
        List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        features.forEach((l) -> System.out.println("lambda expression for list:" + l));
    }

    public static void filter(List names, Predicate condition) {
        names.forEach((n) -> {
            if (condition.test(n)) System.out.println(n);
        });
    }

    //函数式编程，过滤内容
    public static void predicateExample() {
        List<String> features = Arrays.asList("One", "Two", "Three", "Four");

        System.out.println("Print all startsWith  \'T\':");
        filter(features, (str) -> ((String) str).startsWith("T"));
    }

    public static void mutiplePredicateExample() {
        List<String> features = Arrays.asList("One", "Two", "Three", "Four");

        System.out.println("Print all startsWithT  and containE:");
        Predicate startsWithT = (str) -> ((String) str).startsWith("T");
        Predicate containE = (str) -> ((String) str).contains("e");
        filter(features, startsWithT.and(containE));
    }

    public static void mapReduceV1() {
        List features = Arrays.asList(1, 2, 3, 4, 5);

        System.out.println("lambda expression for mapReduceV1:");
        features.stream().map((num) -> (Integer) num * (Integer) num).forEach((n) -> System.out.println(n));
    }

    public static void mapReduceV2() {
        List<Integer> features = Arrays.asList(1, 2, 3, 4, 5);

        System.out.println("lambda expression for mapReduceV2:");
        //没有初始值返回Optional
        Optional<Integer> result_1 = features.stream().map((num) -> num * 1).reduce((a, b) -> a * b);
        System.out.println(result_1.get());
        //有初始值返回结果
        Integer result = features.stream().map((num) -> num * 1).reduce(10, (a, b) -> a * b);
        System.out.println(result);
    }

    public static void streamFilter() {
        List<String> features = Arrays.asList("One", "Two", "Three", "Four");
        System.out.println("lambda expression for streamFilter:");

        List<String> filterlist = features.stream().filter(x -> x.length() > 3).collect(Collectors.toList());
        System.out.println(filterlist);
    }

    public static void joinString() {
        List<String> features = Arrays.asList("One", "Two", "Three", "Four");

        System.out.println("lambda expression for joinString:");
        String joinString = features.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(","));
        System.out.println(joinString);
    }

    public static void distinct() {
        List<String> features = Arrays.asList("One", "Two", "Three", "One", "Two", "Four");

        System.out.println("lambda expression for distinct:");
        List<String> distinct = features.stream().distinct().collect(Collectors.toList());
        System.out.printf("Original List : %s, Without duplicates : %s %n", features, distinct);
    }

    public static void summaryStatistics() {
        List<Integer> features = Arrays.asList(1, 2, 3, 4, 5);
        System.out.println("lambda expression for summaryStatistics:");

        IntSummaryStatistics statistics = features.stream().mapToInt(x -> x).summaryStatistics();
        System.out.println("Max=" + statistics.getMax());
        System.out.println("Min=" + statistics.getMin());
        System.out.println("Average=" + statistics.getAverage());
        System.out.println("Count=" + statistics.getCount());
        System.out.println("Sum=" + statistics.getSum());

    }


    public static void main(String[] args) {
        newThread("lambda expression for thread 1!");
        newThread("lambda expression for thread 2!");
//        buttonListener();
        forList();
        predicateExample();
        mutiplePredicateExample();
        mapReduceV1();
        mapReduceV2();
        streamFilter();
        joinString();
        distinct();
        summaryStatistics();
    }
}

/**
 * 输出结果:

 lambda expression for thread 1!
 lambda expression for thread 2!
 lambda expression for list:Lambdas
 lambda expression for list:Default Method
 lambda expression for list:Stream API
 lambda expression for list:Date and Time API
 Print all startsWith  'T':
 Two
 Three
 Print all startsWithT  and containE:
 Three
 lambda expression for mapReduceV1:
 1
 4
 9
 16
 25
 lambda expression for mapReduceV2:
 120
 1200
 lambda expression for streamFilter:
 [Three, Four]
 lambda expression for joinString:
 ONE,TWO,THREE,FOUR
 lambda expression for distinct:
 Original List : [One, Two, Three, One, Two, Four], Without duplicates : [One, Two, Three, Four]
 lambda expression for summaryStatistics:
 Max=5
 Min=1
 Average=3.0
 Count=5
 Sum=15
 */
